#include <stdio.h>	//standard i/o
#include <dlfcn.h>	//dlopen,dlsym,dlclose functions

int main(){

	double x;
	double (*power1)(double y,int z);
	double (*modul1)(double y);		
	int factx,n;
	unsigned int (*factorial1)(int k);
	char f;
	void *op;

	printf("Enter operation <'^','!','a'>\n");			//enter of operation
	scanf("%c",&f);
	switch (f){
		case '^':					
			printf("Enter arguments\n");			//enter of arguments
			scanf("%lf%d",&x,&n);
			if ((x==0 && n==0)||(n<0)){			//checking if arguments correct
				printf("Invalid arguments\n");
				return 0;
			}
			else{
				op=dlopen("./libf.so",RTLD_LAZY);	//load library
				power1=dlsym(op,"power");		//call of applicable function
				printf("f(x)=%lf\n",(*power1)(x,n));	
				dlclose(power1);			//unload library
				return 0;
			}
		case '!': 
			printf("Enter argument\n");
			scanf("%d",&factx);
			if (factx<0){
				printf("Invalid argument\n");
				return 0;
			}
			else{
				op=dlopen("./libf.so",RTLD_LAZY);
				factorial1=dlsym(op,"factorial");
				printf("f(x)=%u\n",(*factorial1)(factx));
				dlclose(op);
				return 0;
			}
		case 'a':
			printf("Enter argument\n");
			scanf("%lf",&x);
			op=dlopen("./libf.so",RTLD_LAZY);
			modul1=dlsym(op,"modul");
			printf("f(x)=%lf\n",(*modul1)(x));
			dlclose(op);
			return 0;
		default:						//checking if operation correct
			printf("Invalid operation\n");
			return 0;
	}
}
